import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:kq_flutter_core_widget/utils/kq_screen_util.dart';
import 'package:kq_flutter_core_widget/utils/native/ble_native_util.dart';
import 'package:kq_flutter_core_widget/utils/toast_util.dart';
import 'package:kq_flutter_core_widget/widgets/button/kq_ink_well.dart';

/// 蓝牙demo
class BleDemo extends StatefulWidget {
  const BleDemo({Key? key}) : super(key: key);

  @override
  BleDemoState createState() => BleDemoState();
}

class BleDemoState extends State<BleDemo> {
  bool bleEnable = false;
  List<BleDevice> devices = [];
  final Map<BleDevice, bool> _deviceOpenStatus = {};

  bool isScanEnd = true;

  @override
  void initState() {
    super.initState();
    BleNativeUtil.isBleOpen().then((value) {
      if (value != null) {
        setState(() {
          bleEnable = value;
        });
      }
    });
    BleNativeUtil.listenBleEnable((enabled) {
      setState(() {
        bleEnable = enabled;
      });
    });
  }

  @override
  void dispose() {
    super.dispose();
    BleNativeUtil.stopListenBleEnable(removeAll: true);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFFF5F5F5),
      appBar: AppBar(
        title: const Text('蓝牙功能演示'),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          _buildTitle('蓝牙状态监听'),
          Container(
            color: Colors.white,
            padding: const EdgeInsets.symmetric(horizontal: 10),
            child: Row(
              children: [
                const Expanded(
                  child: Text('蓝牙开关状态'),
                ),
                IgnorePointer(
                  child: Switch(
                    value: bleEnable,
                    onChanged: (value) {},
                  ),
                ),
              ],
            ),
          ),
          _buildTitle('蓝牙开关(仅支持Android)'),
          Row(
            children: [
              Expanded(
                child: _buildBtn(
                  '打开蓝牙（仅Android可用）',
                  padding: const EdgeInsets.all(8.0),
                  onTap: BleNativeUtil.openBle,
                ),
              ),
              Expanded(
                child: _buildBtn(
                  '关闭蓝牙(Android 12+失效)',
                  padding: const EdgeInsets.all(8.0),
                  onTap: BleNativeUtil.closeBle,
                ),
              ),
            ],
          ),
          _buildTitle('搜索蓝牙'),
          Container(
            height: 40,
            padding: EdgeInsets.symmetric(vertical: 4.r, horizontal: 6),
            child: Row(
              children: [
                Expanded(child: Text("${devices.length}个蓝牙设备，结束$isScanEnd")),
                _buildBtn(
                  '开始搜索',
                  onTap: () {
                    setState(() {
                      devices.clear();
                      _deviceOpenStatus.clear();
                    });
                    BleNativeUtil.startScanBle(
                      scanCallback: (isComplete, device) {
                        setState(() {
                          if (device != null && device.name != "NULL") {
                            devices.add(device);
                          }
                          isScanEnd = isComplete;
                        });
                      },
                    );
                  },
                ),
                const SizedBox(width: 10),
                _buildBtn(
                  '结束搜索',
                  onTap: () async {
                    var stopScanBle = await BleNativeUtil.stopScanBle();
                    if (stopScanBle != null) {
                      setState(() {
                        isScanEnd = stopScanBle;
                      });
                    }
                  },
                ),
              ],
            ),
          ),
          Expanded(child: _buildList())
        ],
      ),
    );
  }

  Widget _buildTitle(String title) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 10),
      child: Text(title),
    );
  }

  Widget _buildBtn(String title,
      {EdgeInsets? padding, GestureTapCallback? onTap}) {
    Widget result = Text(
      title,
      style: const TextStyle(fontSize: 12),
    );

    result = FilledButton(
      onPressed: onTap,
      child: result,
    );

    if (padding != null) {
      result = Padding(padding: padding, child: result);
    }
    return result;
  }

  Widget _buildList() {
    if (devices.isEmpty) {
      return const SizedBox();
    }

    return ListView.builder(
      itemCount: devices.length,
      itemBuilder: (context, index) => _buildCell(index),
    );
  }

  Widget _buildCell(int index) {
    var device = devices[index];

    var services = device.services;
    var length = services?.length ?? 0;

    Widget result = Column(
      children: [
        KqInkWell(
          horizontalPadding: 20,
          verticalPadding: 8,
          onTap: () {
            connectDevice(device);
          },
          child: Column(
            children: [
              Row(
                children: [
                  Expanded(child: Text(device.name ?? "未知")),
                  _buildTagView(
                    device.connectState?.getName() ?? '',
                    device.connectState == BleConnectState.connected
                        ? Colors.green
                        : Colors.red,
                  )
                ],
              ),
              const SizedBox(height: 20),
              Row(
                children: [
                  Expanded(child: Text(device.macAddress ?? '')),
                  Text('${device.rssi ?? 0}'),
                ],
              ),
            ],
          ),
        ),
        if (length > 0)
          SizedBox(
            height: 24,
            width: 100,
            child: _buildBtn(
              _deviceOpenStatus[device] == true ? '收起' : '展开',
              onTap: () {
                _deviceOpenStatus[device] = _deviceOpenStatus[device] != true;
                setState(() {});
              },
            ),
          ),
        if (length > 0) const SizedBox(height: 10),
        // 服务列表
        if (_deviceOpenStatus[device] == true && length > 0)
          ...device.services!.map((e) => _buildServices(device, e)).toList()
      ],
    );
    if (index % 2 == 0) {
      result = ColoredBox(
        color: Colors.white,
        child: result,
      );
    }
    return result;
  }

  Widget _buildTagView(String value, Color color) {
    Widget result = Text(
      value,
      style: TextStyle(fontSize: 8, color: color),
    );
    result = DecoratedBox(
      decoration: BoxDecoration(border: Border.all(color: color, width: 0.5)),
      child: result,
    );
    return result;
  }

  Widget _buildServices(BleDevice device, BleGattService service) {
    Widget result = Column(
      children: [
        Row(
          children: [
            Expanded(
              child: Text(
                '${service.uuid} (${service.characters?.length ?? ""})',
                style: const TextStyle(
                  fontSize: 14,
                ),
              ),
            ),
          ],
        ),
        ...(service.characters
                ?.map(
                  (e) => _buildCharacters(device, service, e),
                )
                .toList()) ??
            []
      ],
    );
    result = Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
      child: result,
    );
    result = ColoredBox(
      color: Colors.black12,
      child: result,
    );
    return result;
  }

  Widget _buildCharacters(
      BleDevice device, BleGattService service, BleGattCharacter character) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 6),
      color: Colors.blueGrey,
      child: Column(
        children: [
          Row(
            children: [
              Expanded(
                  child: Text(
                '${character.uuid}',
                style: const TextStyle(fontSize: 14, color: Colors.white),
              )),
            ],
          ),
          if (character.extraData != null)
            KqInkWell(
              onTap: () {
                Clipboard.setData(ClipboardData(
                    text: toHexList(character.extraData, showHint: false)));
                KqToast.showSuccess("已复制到剪贴板");
              },
              child: Container(
                color: Colors.yellowAccent,
                margin: const EdgeInsets.only(top: 8, bottom: 8),
                padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4),
                child: Row(
                  children: [
                    Expanded(
                        child: Text(
                      toHexList(character.extraData),
                      style: const TextStyle(
                          fontSize: 15, fontFamily: 'Courier New'),
                    )),
                  ],
                ),
              ),
            ),
          if (device.connectState == BleConnectState.connected)
            Container(
              margin: const EdgeInsets.only(top: 6),
              child: Row(
                children: [
                  _buildBtn(
                    "Notify开",
                    onTap: () async {
                      bool? notify = await BleNativeUtil.notify(
                        device: device,
                        service: service.uuid ?? '',
                        character: character.uuid ?? '',
                        callback: (service, character1, data) {
                          print(data);
                          KqToast.showSuccess(
                              "收到${character1}的数据，长度${data.length}");
                          setState(() {
                            character.extraData = data;
                          });
                        },
                      );
                      if (notify != null && notify) {
                        KqToast.showSuccess("Notify已打开");
                      } else {
                        KqToast.showSuccess("Notify打开失败");
                      }
                    },
                  ),
                  const SizedBox(width: 20),
                  _buildBtn(
                    "Notify关",
                    onTap: () async {
                      bool? notify = await BleNativeUtil.unNotify(
                          device: device,
                          service: service.uuid ?? '',
                          character: character.uuid ?? '');
                      if (notify != null && notify) {
                        KqToast.showSuccess("Notify已关闭");
                      }
                    },
                  ),
                  const SizedBox(width: 20),
                  _buildBtn(
                    '写入数据',
                    onTap: () => _writeData(device, service, character),
                  )
                ],
              ),
            )
        ],
      ),
    );
  }

  void _writeData(
      BleDevice device, BleGattService service, BleGattCharacter character) {
    var controller = TextEditingController(text: "55 33 01 3E b1 27");
    showDialog(
      context: context,
      builder: (context) {
        Widget result = TextField(
          controller: controller,
        );
        result = SizedBox(
          height: 30,
          child: result,
        );
        result = Column(
          children: [
            result,
            const SizedBox(height: 20),
            _buildBtn(
              '写入数据',
              onTap: () async {
                Navigator.pop(context);
                List<int> data = hexStringToBytes(controller.text);
                var writeOk = await BleNativeUtil.writeCharacterData(
                    device: device,
                    service: service.uuid ?? '',
                    character: character.uuid ?? '',
                    value: data);
                if (writeOk != null && writeOk) {
                  KqToast.showSuccess("写入成功");
                }
              },
            )
          ],
        );
        result = Container(
          alignment: Alignment.center,
          color: Colors.white,
          height: 100,
          width: 300,
          child: result,
        );
        result = UnconstrainedBox(
          child: result,
        );
        return result;
      },
    );
  }

  List<int> hexStringToBytes(String hexString) {
    List<String> hexValues = hexString.split(' ');
    List<int> byteList = [];

    for (String hex in hexValues) {
      int decimalValue = int.parse(hex, radix: 16);
      byteList.add(decimalValue);
    }

    return byteList;
  }

  void connectDevice(BleDevice device) async {
    if (device.connectState == BleConnectState.connected) {
      await BleNativeUtil.disConnectDevice(device: device);
      return;
    }
    EasyLoading.show(status: "正在连接...");
    BleConnectResult? result = await BleNativeUtil.connectDevice(
      device: device,
      stateCallback: (macAddress, connectState) {
        print("connectState=$connectState");
        if (device.connectState != connectState) {
          KqToast.showNormal("蓝牙${connectState.getName()}");
          setState(() {
            device.connectState = connectState;
          });
        }
      },
    );
    EasyLoading.dismiss();
    if (result == null || result.connectState != BleConnectState.connected) {
      KqToast.showNormal("连接失败");
    } else {
      print(result);
      setState(() {});
      KqToast.showSuccess("连接成功");
    }
  }

  String toHexList(List<int> byteList, {bool showHint = true}) {
    StringBuffer buffer = StringBuffer();

    int count = byteList.length ~/ 10;
    for (int i = 0; i < byteList.length; i += 10) {
      // 获取当前要处理的10个字节
      List<int> sublist = byteList.sublist(
          i, i + 10 < byteList.length ? i + 10 : byteList.length);

      // 将10个字节转换为十六进制字符串
      String hexString = sublist.map((int byte) {
        return byte.toRadixString(16).padLeft(2, '0');
      }).join(' ');

      // 将十六进制字符串追加到 buffer
      buffer.write(hexString);

      if (showHint) {
        buffer.write("($i~${i + 9})");
      }

      // 换行
      if (i ~/ 10 < count) {
        buffer.writeln();
      }
    }

    // 返回最终的字符串
    return buffer.toString();
  }
}
